//
// Created by chizuru on 2025/9/16.
//

#pragma once


#include <functional>
#include <memory>
#include <mutex>
#include <map>
#include "IProtocolCodec.h"

class ProtocolCodecFactory {
public:
    friend class Registrar;
    using CodecFactoryFn = std::function<std::unique_ptr<IProtocolCodec>()>;
    static ProtocolCodecFactory& instance();
    std::unique_ptr<IProtocolCodec> create(const std::string& name) const;

    struct Registrar {
        Registrar(std::string name, CodecFactoryFn fn) {
            ProtocolCodecFactory::instance().registerFactory(std::move(name), std::move(fn));
        }
    };
private:
    void registerFactory(std::string name, CodecFactoryFn fn);
    ProtocolCodecFactory() = default;
    ProtocolCodecFactory(const ProtocolCodecFactory&) = delete;
    ProtocolCodecFactory& operator=(const ProtocolCodecFactory&) = delete;

private:
    mutable std::mutex mutex;
    std::map<std::string, CodecFactoryFn> factories;
};
